﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Net.Sockets;
using System.Threading;
using System.Text;
using System.Collections.Generic;

namespace V5_PhoneLibs {
    public class SocketClient {

        public delegate void OutSocketDelegate(string fileTitle, string content);
        public OutSocketDelegate Osd;

        private Socket _socket = null;
        private static readonly ManualResetEvent ClientDone = new ManualResetEvent(false);
        private const int TimeoutMilliseconds = 5000;//等待时间
        private const int MaxBufferSize = 512 * 1024;//缓存区域请求大小
        /// <summary>
        /// 连接远程IP
        /// </summary>
        /// <param name="hostName"></param>
        /// <param name="portNumber"></param>
        /// <returns></returns>
        public string Connect(string hostName, int portNumber) {
            string result = string.Empty;
            var hostEntry = new DnsEndPoint(hostName, portNumber);
            _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            var socketEventArg = new SocketAsyncEventArgs();
            socketEventArg.RemoteEndPoint = hostEntry;
            socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e) {
                result = e.SocketError.ToString();
                ClientDone.Set();
            });
            ClientDone.Reset();
            _socket.ConnectAsync(socketEventArg);
            ClientDone.WaitOne(TimeoutMilliseconds);
            return result;
        }


        /// <summary>
        /// 发送数据到服务端
        /// </summary>
        /// <param name="data">The data to send to the server</param>
        /// <returns>The result of the Send request</returns>
        public string Send(string data) {
            string response = "Operation Timeout";
            if (_socket != null) {
                var socketEventArg = new SocketAsyncEventArgs();
                socketEventArg.RemoteEndPoint = _socket.RemoteEndPoint;
                socketEventArg.UserToken = null;
                socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e) {
                    response = e.SocketError.ToString();
                    ClientDone.Set();
                });
                byte[] payload = Encoding.UTF8.GetBytes(data);
                socketEventArg.SetBuffer(payload, 0, payload.Length);
                ClientDone.Reset();
                _socket.SendAsync(socketEventArg);
                ClientDone.WaitOne(TimeoutMilliseconds);
            }
            else {
                response = "Socket is not initialized";
            }
            return response;
        }


        /// <summary>
        /// 从服务器段请求数据
        /// </summary>
        /// <returns>The data received from the server</returns>
        public string Receive() {
            string response = "Operation Timeout";
            if (_socket != null) {
                var socketEventArg = new SocketAsyncEventArgs();
                socketEventArg.RemoteEndPoint = _socket.RemoteEndPoint;
                socketEventArg.SetBuffer(new Byte[MaxBufferSize], 0, MaxBufferSize);
                socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(socketEventArg_Completed);
                ClientDone.Reset();
                _socket.ReceiveAsync(socketEventArg);
                ClientDone.WaitOne(TimeoutMilliseconds);
            }
            else {
                response = "Socket is not initialized";
            }
            return response;
        }
        private List<byte> _listReceive = new List<byte>();
        private string _fileTitle = string.Empty;
        private void socketEventArg_Completed(object sender, SocketAsyncEventArgs e) {
            string response = "Operation Timeout";
            char _splitChar = '^';
            bool _IsReceiveEnd = false;
            if (e.SocketError == SocketError.Success) {
                for (int i = e.Offset; i < e.BytesTransferred; i++) {
                    if (e.Buffer[i] == _splitChar) {
                        _IsReceiveEnd = true;
                    }
                    _listReceive.Add(e.Buffer[i]);
                }
                if (_IsReceiveEnd) {
                    string content = Encoding.UTF8.GetString(_listReceive.ToArray(), 0, _listReceive.Count);
                    _listReceive.Clear();
                    _listReceive = new List<byte>();
                    if (Osd != null) {
                        Osd(_fileTitle, content);
                    }
                }
                else {
                    Receive();
                }
            }
            else {
                response = e.SocketError.ToString();
            }
            ClientDone.Set();
        }


        /// <summary>
        /// 关闭连接对象
        /// </summary>
        public void Close() {
            if (_socket != null) {
                _socket.Close();
            }
        }

    }
}
